using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Content;

namespace XNALibrary.PostProcessing
{
    public class PostProcessing
    {
        private SpriteBatch sprite;
        private RenderTarget2D renderTarget;
        private Effect shader;
        private GraphicsDevice device;
        private ContentManager content;


        #region Properties and Enums
        public Effect Shader
        {
            get { return shader; }
            set { shader = value; }
        }

        public enum PostEffect
        {
            NormalRender,
            HDR,
            HotVision,
            BlackWhite,
            OldMovie,
            PostInvert,
            Silouette
        }
        #endregion

        public PostProcessing(GraphicsDevice device, ref ContentManager content)
        {
            this.device = device;
            this.content = content;
        }

        public void Initialize()
        {
            shader = content.Load<Effect>("Resources\\Effects\\NormalRender");
            InitRT();
        }

        public void Initialize(string pathShader)
        {
            shader = content.Load<Effect>(pathShader);
            InitRT();
        }

        public void Initialize(PostEffect effect)
        {
            switch (effect)
            {
                case PostEffect.NormalRender:
                    shader = content.Load<Effect>("Resources\\Effects\\NormalRender");
                    break;
                case PostEffect.HDR:
                    shader = content.Load<Effect>("Resources\\Effects\\HDR");
                    break;
                case PostEffect.HotVision:
                    shader = content.Load<Effect>("Resources\\Effects\\HotVision");
                    break;
                case PostEffect.BlackWhite:
                    shader = content.Load<Effect>("Resources\\Effects\\BlackWhite");
                    break;
                case PostEffect.OldMovie:
                    shader = content.Load<Effect>("Resources\\Effects\\OldMovie");
                    break;
                case PostEffect.PostInvert:
                    shader = content.Load<Effect>("Resources\\Effects\\PostInvert");
                    break;
                case PostEffect.Silouette:
                    shader = content.Load<Effect>("Resources\\Effects\\Silouette");
                    break;
            }

            InitRT();
        }

        private void InitRT()
        {
            renderTarget = new RenderTarget2D(device,
                device.Viewport.Width,
                device.Viewport.Height,
                1,
                device.DisplayMode.Format);

            sprite = new SpriteBatch(device);
        }

        public void PreRender()
        {
            device.SetRenderTarget(0, renderTarget);
        }

        public void PostRender()
        {
            device.ResolveRenderTarget(0);
            device.SetRenderTarget(0, null);

            shader.Begin();
            sprite.Begin(SpriteBlendMode.None, SpriteSortMode.Immediate, SaveStateMode.SaveState);

            foreach (EffectPass pass in shader.CurrentTechnique.Passes)
            {
                pass.Begin();
                sprite.Draw(renderTarget.GetTexture(), Vector2.Zero, Color.White);
                pass.End();
            }
            sprite.End();
            shader.End();
        }

    }
}
